package com.example.aigc_education.controller;

import com.example.aigc_education.anno.RequestKeyParam;
import com.example.aigc_education.anno.RequestLock;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.User;
import com.example.aigc_education.domain.request.*;
import com.example.aigc_education.domain.vo.GenCacheVO;
import com.example.aigc_education.integration.request.ChatMessageRequest;
import com.example.aigc_education.integration.threeparty.ChatglmService;
import com.example.aigc_education.integration.threeparty.CozeService;
import com.example.aigc_education.integration.threeparty.ZhipuService;
import com.example.aigc_education.service.AlgoService;
import com.example.aigc_education.utils.ResultUtil;
import com.example.aigc_education.utils.SecurityUtils;
import com.zhipu.oapi.service.v4.model.SSE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/llmApp")
public class LlmAppController {

    @Resource
    private AlgoService algoService;

    @Resource
    private CozeService cozeService;

    @Resource
    private ChatglmService chatglmService;

    @Resource
    private ZhipuService zhipuService;

    /**
     * 连接
     * @return SseEmitter
     */
    @GetMapping(value = "/connect/{messageId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter connect(@PathVariable("messageId") Long messageId) {
        return algoService.connect(messageId);
    }


    /**
     * AI对话
     * @param request 对话内容
     */
    @PostMapping(value = "/chat")
    public ResultUtil chat(@RequestBody ChatAiContentRequest request) {
        ChatMessageRequest response;
        try {
            response = algoService.chat(request);
        } catch (Exception e) {
            log.info("AlgoServiceImpl-chat error:{}", e.getMessage());
            throw new BusinessException("AI对话失败");
        }
        return ResultUtil.success(response);
    }


    /**
     * AI生成学习计划
     * @return
     */
    @RequestLock(prefix = "aiGenStudyPlan:",expire = 3)
    @PostMapping(value = "/aigc/study_plan")
    public ResultUtil aiGenStudyPlan(@Validated @RequestBody @RequestKeyParam GenStudyPlanRequest request){
        Long userId = SecurityUtils.getUserId();
        if (userId == null) {
            throw new BusinessException("用户未登录");
        }
        return cozeService.genStudyPlan(userId, request.getTitle(), request.getSubject(), request.getGrade(), request.getGoal(), request.getLanguage());
    }

    /**
     * AI生成学习计划V2
     * @return
     */
    @RequestLock(prefix = "aiGenStudyPlanV2:",expire = 3)
    @PostMapping(value = "/aigc/study_plan/v2")
    public ResultUtil aiGenStudyPlanV2(@Validated @RequestBody @RequestKeyParam GenStudyPlanV2Request request){
//        Long userId = SecurityUtils.getUserId();
        User loginUser = Objects.requireNonNull(SecurityUtils.getLoginUser()).getUser();
        if (loginUser == null) {
            throw new BusinessException("用户未登录");
        }
        return cozeService.genStudyPlanV2(loginUser, request.getTitle(), request.getSubject(), request.getStage(), request.getTargetLevel(), request.getPriority(),request.getCoverUrl());
    }

    /**
     * AI生成学习计划封面
     * @return
     */
    @RequestLock(prefix = "aiGenPlanCoverImg:",expire = 3)
    @PostMapping(value = "/aigc/study_plan/coverImg")
    public ResultUtil aiGenPlanCoverImg(@Validated @RequestBody @RequestKeyParam GenPlanCoverImgRequest request){
        return zhipuService.GenPlanCoverImg(request.getSubject(),request.getTitle());
    }

    /**
     * AI生成学习测验
     * @return
     */
    @RequestLock(prefix = "aiGenQuizzes:",expire = 3)
    @PostMapping(value = "/aigc/quiz")
    public ResultUtil aiGenQuizzes(@Validated @RequestBody @RequestKeyParam GenStudyQuizRequest request){
        return cozeService.genQuizzes(request.getTopic(), request.getSubtopic(), request.getQuizzesNum(), request.getDifficulty());
    }

    /**
     * AI生成学习测验V2(异步)
     * @return
     */
    @RequestLock(prefix = "aiGenQuizzesV2:",expire = 3)
    @PostMapping(value = "/aigc/quiz/v2")
    public ResultUtil aiGenQuizzesV2(@Validated @RequestBody @RequestKeyParam GenStudyQuizV2Request request){
        return cozeService.asyncGenQuizzesV2(request.getTopic(), request.getSubtopic(), request.getQuestionNum(), request.getDifficulty(), request.getQuestionType(), request.getUrl(), request.getUrlType(), request.getFilename());
    }

    /**
     * 查询任务状态
     * @param executeId 执行ID
     * @param taskType 任务类型
     */
    @GetMapping("/aigc/task_status/{executeId}/{taskType}")
    public ResultUtil queryTaskStatus(@PathVariable String executeId, @PathVariable String taskType){
        return cozeService.queryAITaskStatus(executeId, taskType);
    }

    /**
     * AI生成学习抽认卡
     * @return
     */
    @RequestLock(prefix = "aiGenFlashcards:",expire = 3)
    @PostMapping(value = "/aigc/flashcard")
    public ResultUtil aiGenFlashcards(@Validated @RequestBody @RequestKeyParam GenStudyFlashcardsRequest request){
        return cozeService.genFlashcards(request.getTopic(), request.getSubtopic(), request.getFlashcardsNum(), request.getDifficulty());
    }

    /**
     * AI生成学习抽认卡V2
     * @return
     */
    @RequestLock(prefix = "aiGenFlashcardsV2:",expire = 3)
    @PostMapping(value = "/aigc/flashcard/v2")
    public ResultUtil aiGenFlashcardsV2(@Validated @RequestBody @RequestKeyParam GenStudyFlashcardsV2Request request){
        return cozeService.asyncGenFlashcardsV2(request.getTopic(), request.getSubtopic(), request.getCardNum(), request.getDifficulty(), request.getUrl(), request.getUrlType(), request.getFilename());
    }

    /**
     * AI学习资源搜索
     * @return
     */
    @RequestLock(prefix = "aiGenWebSearch:",expire = 3)
    @PostMapping(value = "/aigc/webSearch")
    public ResultUtil aiGenWebSearch(@RequestKeyParam @NotBlank(message = "主题不能为空") String subtopic){
        return cozeService.webSearch(subtopic);
    }

    /**
     * 前端轮询
     * 查询学习计划生成状态
     * @return
     */
    @GetMapping(value = "/aigc/study_plan/status/{planId}")
    public ResultUtil queryStudyPlanStatus(@PathVariable Long planId){
        return cozeService.queryStudyPlanStatus(planId);
    }

    /**
     * 服务端sse推送，推送学习计划生成状态
     * @return
     */
    @GetMapping(value = "/aigc/study_plan/push/{planId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter pushStudyPlanStatus(@PathVariable Long planId){
        return cozeService.pushStudyPlanStatus(planId);
    }

    /**
     * 上传文件，ocr识别 --》 调用connect
     * @param file 文件
     * @return 识别结果,AI根据识别结果回复用户
     */
    @PostMapping("/aigc/ocr")
    public SseEmitter ocr(@RequestParam("file") MultipartFile file){
        ChatAiContentRequest request = chatglmService.ocrContentRequest(file);
//        ChatMessageRequest response = chatglmService.chat(request);
        return chatglmService.docChatSse(request);
    }


    /**
     * 文档问答
     * @param request 文档内容
     */
    // @PostMapping("/aigc/document_qa")
    // public ResultUtil docChat(@RequestBody ChatAiContentRequest request){
    //     ChatMessageRequest response = chatglmService.chat(request);
    //     return ResultUtil.success(response);
    // }

    @PostMapping("/aigc/document_qa/sse")
    public SseEmitter docChatSse(@RequestBody ChatAiContentRequest request){
        return chatglmService.docChatSse(request);
    }

    /**
     * 获取用户生成数据缓存
     * @return
     */
    @GetMapping("/genCache/get")
    public ResultUtil getGenCache(){
        Long userId = SecurityUtils.getUserId();
        GenCacheVO genCache = cozeService.getGenCache(userId);
        if (genCache == null){
            return ResultUtil.success("用户无生成数据缓存");
        }else {
            return ResultUtil.success(genCache);
        }
    }
}
